package org.example.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.MybatisSqlSessionFactoryBuilder;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.logging.slf4j.Slf4jImpl;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.example.mapper.ColumnInfoMapper;
import org.example.mapper.ColumnRelationMapper;
import org.example.mapper.TableInfoMapper;
import org.sqlite.SQLiteDataSource;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * MyBatis-Plus配置类
 */
@Slf4j
public class MybatisPlusConfig {
    private static final String DB_URL = "jdbc:sqlite:sedinfo.db";
    private static SqlSessionFactory sqlSessionFactory;
    private static final String MAPPER_PATH = "mapper";

    /**
     * 获取SqlSessionFactory实例
     */
    public static SqlSessionFactory getSqlSessionFactory() {
        if (sqlSessionFactory == null) {
            synchronized (MybatisPlusConfig.class) {
                if (sqlSessionFactory == null) {
                    sqlSessionFactory = buildSqlSessionFactory();
                }
            }
        }
        return sqlSessionFactory;
    }

    /**
     * 构建SqlSessionFactory
     */
    private static SqlSessionFactory buildSqlSessionFactory() {
        try {
            // 创建数据源
            DataSource dataSource = createDataSource();

            // 创建MyBatis-Plus配置
            MybatisConfiguration configuration = new MybatisConfiguration();
            configuration.setLogImpl(Slf4jImpl.class);
            configuration.setMapUnderscoreToCamelCase(true);
            
            // 添加分页插件
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.SQLITE));
            configuration.addInterceptor(interceptor);

            // 设置环境
            Environment environment = new Environment("development", new JdbcTransactionFactory(), dataSource);
            configuration.setEnvironment(environment);

            // 添加Mapper
            configuration.addMapper(TableInfoMapper.class);
            configuration.addMapper(ColumnInfoMapper.class);
            configuration.addMapper(ColumnRelationMapper.class);

            // 加载所有XML映射文件
            try {
                loadAllMapperXml(configuration);
            } catch (Exception e) {
                throw new RuntimeException("加载Mapper XML文件失败", e);
            }

            // 构建SqlSessionFactory
            return new MybatisSqlSessionFactoryBuilder().build(configuration);
        } catch (Exception e) {
            throw new RuntimeException("构建SqlSessionFactory失败", e);
        }
    }

    /**
     * 加载所有Mapper XML文件
     */
    private static void loadAllMapperXml(MybatisConfiguration configuration) throws Exception {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Enumeration<URL> urls = loader.getResources(MAPPER_PATH);
        
        while (urls.hasMoreElements()) {
            URL url = urls.nextElement();
            List<String> resources = getResourceListing(url.toString());
            
            for (String resource : resources) {
                if (resource.endsWith(".xml")) {
                    String mapperPath = MAPPER_PATH + "/" + resource;
                    log.info("正在加载Mapper XML文件: {}", mapperPath);
                    loadXmlMapper(configuration, mapperPath);
                }
            }
        }
    }

    /**
     * 获取资源列表
     */
    private static List<String> getResourceListing(String path) throws IOException {
        List<String> resources = new ArrayList<>();
        try {
            URL url = new URL(path);
            if ("file".equals(url.getProtocol())) {
                java.io.File file = new java.io.File(url.toURI());
                if (file.isDirectory()) {
                    for (java.io.File child : file.listFiles()) {
                        resources.add(child.getName());
                    }
                }
            } else if ("jar".equals(url.getProtocol())) {
                String jarPath = url.getPath().substring(5, url.getPath().indexOf("!"));
                java.util.jar.JarFile jar = new java.util.jar.JarFile(jarPath);
                Enumeration<java.util.jar.JarEntry> entries = jar.entries();
                String prefix = MAPPER_PATH + "/";
                while (entries.hasMoreElements()) {
                    String name = entries.nextElement().getName();
                    if (name.startsWith(prefix) && name.length() > prefix.length()) {
                        resources.add(name.substring(prefix.length()));
                    }
                }
                jar.close();
            }
        } catch (Exception e) {
            log.error("获取资源列表失败: {}", path, e);
        }
        return resources;
    }

    /**
     * 加载XML映射文件
     */
    private static void loadXmlMapper(MybatisConfiguration configuration, String mapperPath) throws Exception {
        try (InputStream inputStream = Resources.getResourceAsStream(mapperPath)) {
            XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(inputStream, 
                configuration, 
                mapperPath, 
                configuration.getSqlFragments());
            xmlMapperBuilder.parse();
        }
    }

    /**
     * 创建SQLite数据源
     */
    private static DataSource createDataSource() {
        SQLiteDataSource dataSource = new SQLiteDataSource();
        dataSource.setUrl(DB_URL);
        return dataSource;
    }
} 